﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using WCBG.ToolsForUnity.Tools;



public class SelectTrainBallPart : StudyMathBasePart
{
    class fellBall
    {
        public int Num;
        public Transform Object;
        public bool Selected;
        public Vector3 OriginPos;
    }

    private const string scenePath = StudyPath.math_selectball_scene;
    private const string trainHeadPath = StudyPath.math_trainHeadPathNoAnim;    // 火车头
    private const string trainNodeBluePath = StudyPath.math_trainNodeBluePath;    // 蓝色车厢
    private const string trainNodeGreenPath = StudyPath.math_trainNodeGreenPath;    // 绿色车厢
    private const string nodeTextureBasePath = "texture/texture_math_png/303020202_num";
    
    private Transform m_train;
    private Transform m_trainStartPoint;
    private Transform m_trainCenterPoint;
    private Transform m_trainEndPoint;
    private Transform m_Bucket;
    private Transform m_Bucket_Start;
    private Transform m_Bucket_End;
    private Transform m_BallParent;
    private Transform m_positionParent;
    private Transform m_HandClick;

    private GameAudioSource m_trainLoopAudio;   // 火车循环跑动音效

    private List<fellBall> m_fallBalls = new List<fellBall>();
    private List<Transform> m_ballPositions = new List<Transform>();

    private Dictionary<int, TrainNodeActor> m_trainNodes = new Dictionary<int, TrainNodeActor>();

    private int m_num;

    private bool m_objectAllowClick = true;

    private int m_selectedBalls = 0;

    private List<int> m_playTrainNumbers = new List<int>();

    private TrainHeadActor m_TrainHeadActor;

    private const float m_trainMiddlePosX = 0.8f;
    private const float m_trainEndPosX = 5f;
    private const float m_trainMoveTime = 3f;
    private const float m_ballFallDownTime = 0.6f;

    private const float m_BallParentOriginY = 200;
    private const float m_BallParentOriginX = -190F;
    private const float m_BallParentMoveY = 300;

    private int[] allPlayNumberArray;

    protected override void OnPartStart(params object[] paramArray)
    {
        base.OnPartStart(paramArray);

        allPlayNumberArray = ((List<int>)paramArray[0]).ToArray();
        m_playTrainNumbers.Clear();

        CreateScene(scenePath);

        InitTrainInfo();
        InitBallInfo();

        StartPlayGame(true);
        //SetHighLightTrain();
        
        MedalWindow.Instance.ShowXunzhang(0, false, MedalWindow.EXZCountEnum.Three);

    }

    protected override void OnPartExit()
    {
        base.OnPartExit();
        
        m_fallBalls.Clear();
        m_ballPositions.Clear();
        m_trainNodes.Clear();
        //m_trainDict.Clear();
        //System.Array.Clear(drawNumberArray, 0, drawNumberArray.Length);
        if (m_trainLoopAudio != null) m_trainLoopAudio.Stop();
        m_trainLoopAudio = null;
    }

    protected override void OnMouseDown()
    {
        base.OnMouseDown();

        Transform target = FTools.GetRaycastHitTargetByMousePoint();
        if (target != null)
        {
            OnGameObjectClick(target.gameObject);
        }
    }

    private void StartPlayGame(bool firststart = false)
    {

        m_objectAllowClick = false;
        m_num = GetRandomAnswer();
        m_selectedBalls = 0;
        m_Bucket.position = m_Bucket_Start.position;

        m_Bucket.DOMove(m_Bucket_End.position, 1f).SetEase(Ease.Linear);
        if (!firststart)
        {
            this.AddTimerEx(1000, () =>
            {
                m_HandClick.gameObject.SetActive(true);
            });
        }
        this.PlayAudioEx(StudyAudioName.t_11016);

        for (int i = 0; i < 10; i++)
        {
            if (m_fallBalls[i].Num < m_num)
            {
                m_fallBalls[i].Object.gameObject.SetActive(true);
                m_fallBalls[i].Object.parent = m_BallParent;
                m_fallBalls[i].Object.localPosition = m_fallBalls[i].OriginPos;
                m_fallBalls[i].Object.localScale = Vector3.one;
                m_fallBalls[i].Selected = false;
            }
            else
            {
                m_fallBalls[i].Object.parent = m_BallParent;
                m_fallBalls[i].Object.gameObject.SetActive(false);
            }
        }

        if(m_trainNodes.Keys.Count > 0)
        {
            foreach(TrainNodeActor actor in m_trainNodes.Values)
            {
                GameObject.Destroy(actor.gameObject);
            }
            m_trainNodes.Clear();
        }

        m_positionParent.parent = Scene;

        List<int> Nums = new List<int>();
        Nums.Add(1);
        Nums.Add(2);
        Nums.Add(3);
        Nums.Add(4);
        Nums.Add(5);
        Nums.Add(6);
        Nums.Add(7);
        Nums.Add(8);
        Nums.Add(9);
        Nums.Add(10);

        Nums.Remove(m_num);
        int num1 = Nums[Random.Range(0, Nums.Count)];
        Nums.Remove(num1);
        int num2 = Nums[Random.Range(0, Nums.Count)];
        Nums.Remove(num2);

        int[] n;
        if (Random.Range(1, 4) == 1)
        {
            n = new int[3] { m_num, num1, num2 };
        }
        else if (Random.Range(1, 4) == 2)
        {
            n = new int[3] { num1, m_num, num2 };
        }
        else
        {
            n = new int[3] { num1, num2 ,m_num };
        }
        CreateTrainNode(n);

        m_train.position = m_trainStartPoint.position;
        m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.Move, 0.01f);
        m_trainLoopAudio = this.PlayAudioEx(StudyAudioName.t_11002, true);
        m_train.DOMove(m_trainCenterPoint.position, 3f).SetEase(Ease.Linear).OnComplete(()=> {

            m_trainLoopAudio.Stop();
            m_trainLoopAudio = null;
            m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.Static, 0.01f);
            foreach (TrainNodeActor actor in m_trainNodes.Values)
            {
                actor.GetComponent<TrainNodeActor>().CrossFade(TrainNodeActor.AnimatorNameEnum.Static, 0.01f);
            }
        });

        foreach (TrainNodeActor actor in m_trainNodes.Values)
        {
            actor.GetComponent<TrainNodeActor>().CrossFade(TrainNodeActor.AnimatorNameEnum.Move, 0.01f);
        }

        if (firststart)
        {

            this.PlayActionAudioEx(ActionAudioName.t_1003, () =>
            {
                m_objectAllowClick = true;
                m_HandClick.gameObject.SetActive(true);
            });
        }
        else
        {
            m_objectAllowClick = true;
        }
    }

    private void InitBallInfo()
    {
        m_positionParent = Scene.Find("ballPositions");

        for (int i = 0; i < 10; i++)
        {
            Transform t = m_positionParent.Find(i.ToString());
            m_ballPositions.Add(t);
        }
        
        for (int i = 0; i < 10; i++)
        {
            Transform t = m_BallParent.Find(i.ToString());
            fellBall fall = new fellBall();
            fall.Num = i;
            fall.Object = t;
            fall.Selected = false;
            fall.OriginPos = t.localPosition;
            m_fallBalls.Add(fall);
        }
    }

    private void InitTrainInfo()
    {
        m_train = Scene.Find("Train");
        m_TrainHeadActor = m_train.AddComponentEx<TrainHeadActor>();

        m_trainStartPoint = Scene.Find("TrainStartPoint");
        m_trainCenterPoint = Scene.Find("TrainCenterPoint");
        m_trainEndPoint = Scene.Find("TrainEndPoint");
        m_Bucket = Scene.Find("Bucket");
        m_Bucket_Start = Scene.Find("Bucket_Start");
        m_Bucket_End = Scene.Find("Bucket_End");
        m_BallParent = m_Bucket.Find("BallParent");
        m_HandClick = m_Bucket.Find("hand_click");

        m_HandClick.gameObject.SetActive(false);
    }

    private void CreateTrainNode(int[] Numbers)
    {
        Resource res = ResourceManager.Instance.GetResource(trainNodeBluePath, typeof(GameObject), enResourceType.ScenePrefab);
        if (res.m_content == null)
        {
            Debug.LogError("Load faild!path:" + trainNodeBluePath);
            return;
        }
        Resource res2 = ResourceManager.Instance.GetResource(trainNodeGreenPath, typeof(GameObject), enResourceType.ScenePrefab);
        if (res2.m_content == null)
        {
            Debug.LogError("Load faild!path:" + trainNodeGreenPath);
            return;
        }
        GameObject prefabBlue = res.m_content as GameObject;
        GameObject prefabGreen = res2.m_content as GameObject;

        for (int i = 0; i < Numbers.Length; i++)
        {
            Transform target = null;
            if (i % 2 == 0)
            {
                target = Instantiate(prefabBlue, true).transform;
            }
            else
            {
                target = Instantiate(prefabGreen, true).transform;
            }

            target.name = Numbers[i].ToString();
            target.parent = m_train;
            target.localRotation = Quaternion.Euler(Vector3.zero);
            Transform childNode = m_train.Find("Node" + (i + 1).ToString());
            if (childNode != null)
            {
                target.position = childNode.position;
            }

            //target.gameObject.AddComponent<InputMono>();
            TrainNodeActor node = target.gameObject.AddComponent<TrainNodeActor>();
            node.SetNodeNumber(Numbers[i]);
            node.SetNodeNumberTexture(Numbers[i]);

            m_trainNodes.Add(Numbers[i], node);
        }
    }

    private void MoveBallsIntoTrainNode(Transform Node)
    {
        m_positionParent.parent = Node;
        m_positionParent.localPosition = new Vector3(0,0.1f,0);

        m_objectAllowClick = false;

        for (int i = 0; i < m_num; i++)
        {
            Transform t = m_fallBalls[i].Object;
            Vector3[] path = new Vector3[] { t.position, m_ballPositions[i].position };

            t.DOPath(path, m_ballFallDownTime, PathType.CatmullRom, PathMode.TopDown2D);
            t.DOScale(m_ballPositions[i].localScale.x, m_ballFallDownTime).OnComplete(() =>
            {
                t.parent = Node;
            });
        }
        this.PlayAudioEx(StudyAudioName.t_11004);
        this.AddTimerEx(m_ballFallDownTime, () => {

            m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.BallTrainFinish, 0.01f);
            foreach (TrainNodeActor actor in m_trainNodes.Values)
            {
                actor.GetComponent<TrainNodeActor>().CrossFade(TrainNodeActor.AnimatorNameEnum.UpAndDown, 0.01f);
            }

        });

        AddTimer(1000, () => {
            m_Bucket.DOKill();

            m_Bucket.DOMove(new Vector3(m_Bucket.position.x, m_Bucket_Start.position.y, m_Bucket.position.z), 1).SetEase(Ease.Linear);
            this.PlayAudioEx(StudyAudioName.t_11016);
        });

        AddTimer(1000, () =>
        {
            GameAudioSource audio = this.PlayAudioEx(StudyAudioName.t_11001);
            AddTimer(audio.Length, () => {

                foreach (TrainNodeActor actor in m_trainNodes.Values)
                {
                    actor.GetComponent<TrainNodeActor>().CrossFade(TrainNodeActor.AnimatorNameEnum.Move, 0.01f);
                }

                m_trainLoopAudio = this.PlayAudioEx(StudyAudioName.t_11002, true);
                m_TrainHeadActor.CrossFade(TrainHeadActor.AnimatorNameEnum.Move, 0.01f);
                m_train.DOMove(m_trainEndPoint.position, m_trainMoveTime).SetEase(Ease.Linear).OnComplete(() =>
                {
                    m_trainLoopAudio.Stop();
                    m_trainLoopAudio = null;

                    AddTimer(1000, () =>
                    {
                        //this.PlayAudioEx(StudyAudioName.t_11018);
                        m_playTrainNumbers.Add(m_num);

                        if (m_playTrainNumbers.Count >= 3)
                        {
                            MedalWindow.Instance.ShowXunzhang(m_playTrainNumbers.Count, true, MedalWindow.EXZCountEnum.Three, () =>
                            {
                                OnPartComplete(true, m_playTrainNumbers);
                            });
                        }
                        else
                        {
                            MedalWindow.Instance.ShowXunzhang(m_playTrainNumbers.Count, true, MedalWindow.EXZCountEnum.Three, () =>
                            {
                                StartPlayGame();
                            });
                        }

                    }
                    );
                });
            });
        });
    }


    private void OnGameObjectClick(GameObject go)
    {
        if (m_objectAllowClick)
        {
            bool isReturn = false;
            int count = m_fallBalls.Count;
            for (int i = 0; i < count; i++)
            { 
                if(m_fallBalls[i].Object == go.transform && !m_fallBalls[i].Selected)
                {
                    m_fallBalls[i].Selected = true;
                    go.transform.localScale *= 1.2f;
                    m_selectedBalls++;
                    if (m_HandClick.gameObject.activeSelf)
                        m_HandClick.gameObject.SetActive(false);

                    //string name = (int.Parse(StudyAudioName.talk_403020202) + m_selectedBalls - 1).ToString();
                    GameAudioSource audio = this.PlayAudioEx(StudyAudioName.t_11015);
                    int index = m_selectedBalls - 1;
                    this.AddTimerEx(audio.Length, () => {

                        GameAudioSource Audio1 = this.PlayAudioEx(StudyAudioName.t_12006 + (uint)index);//PlayMathAudio(name);

                        if (m_selectedBalls >= m_num)
                        {
                            m_objectAllowClick = false;
                            AddTimer(Audio1.Length, () =>
                            {
                                //GameAudioSource Audio2 = PlayMathAudio(StudyAudioName.talk_403020403_x + m_selectedBalls.ToString());
                                //AddTimer(Audio2.Length, () =>
                                //{
                                //GameAudioSource Audio3 = PlayMathAudio(StudyAudioName.talk_403020404);
                                //AddTimer(Audio3.Length, () =>
                                //{
                                m_objectAllowClick = true;
                                foreach (TrainNodeActor ac in m_trainNodes.Values)
                                {
                                    ac.GetComponent<TrainNodeActor>().PlayEffect(StudyPath.math_traineffect_hint);
                                }
                                //});
                                //});
                            });
                        }
                    });
                    isReturn = true;
                    break;
                }
            }

            TrainHeadActor headactor = go.GetComponent<TrainHeadActor>();
            if (headactor != null)
            {
                headactor.CrossFade(TrainHeadActor.AnimatorNameEnum.Zoom, 0.01f);
                isReturn = true;
                return;
            }

            TrainNodeActor actor = go.GetComponent<TrainNodeActor>();
            if (actor != null)
            {
                if (m_selectedBalls >= m_num)
                {
                    foreach (TrainNodeActor ac in m_trainNodes.Values)
                    {
                        ac.GetComponent<TrainNodeActor>().StopEffect();
                    }

                    //球够了
                    if (actor.Number == m_num)
                    {
                        m_objectAllowClick = false;

                        this.PlayAudioEx(StudyAudioName.t_12025);
                        this.PlayAudioEx(StudyAudioName.t_11016);
                        m_Bucket.DOMoveX(go.transform.position.x, 1.0f).OnComplete(() =>
                        {
                            Animator ani = m_Bucket.GetComponentInChildren<Animator>();
                            ani.Play("bucket_scroll");

                            AddTimer(700, () =>
                            {
                                MoveBallsIntoTrainNode(go.transform);
                            });

                            AddTimer(1500, () =>
                            {
                                m_Bucket.DOMoveY(m_BallParentMoveY, 1.5f);
                            });
                        });
                    }
                    else
                    {

                        actor.CrossFade(TrainNodeActor.AnimatorNameEnum.RightAneLeft, 0.01f);
                        this.PlayAudioEx(StudyAudioName.t_11006);
                        GameAudioSource Audio1 = this.PlayAudioEx(StudyAudioName.t_12026);
                        m_objectAllowClick = false;
                        AddTimer(Audio1.Length, () =>
                        {
                            m_objectAllowClick = true;
                        });
                    }
                }
                else
                {
                    //不够
                    actor.CrossFade(TrainNodeActor.AnimatorNameEnum.RightAneLeft, 0.01f);
                    this.PlayAudioEx(StudyAudioName.t_11006);
                }

                isReturn = true;
            }

            if (!isReturn)
                go.AddComponentEx<StudyFixedActor>().CrossFade(StudyFixedActor.AnimatorNameEnum.Jump, 0.01f);

        }
        //OnPartComplete(go.GetComponent<TrainHeadMono>().Number);
    }

    private int GetRandomAnswer()
    {
        List<int> Nums = new List<int>();
        Nums.Add(1);
        Nums.Add(2);
        Nums.Add(3);
        Nums.Add(4);
        Nums.Add(5);
        Nums.Add(6);
        Nums.Add(7);
        Nums.Add(8);
        Nums.Add(9);
        Nums.Add(10);

        for(int i = 0;i < allPlayNumberArray.Length;i++)
        {
            Nums.Remove(allPlayNumberArray[i]);
        }

        for (int i = 0; i < m_playTrainNumbers.Count; i++)
        {
            Nums.Remove(m_playTrainNumbers[i]);
        }

        if (Nums.Count > 0)
        {
            return Nums[Random.Range(0, Nums.Count)];
        }
        else
        {
            return 1;
        }
    }
}
